#include <stdlib.h>
#include <time.h>
#include <stdio.h>

#include "bird.h"
#include "ssd1306/ssd1306.h"




static const unsigned char bitmap_bird[] = {
0x03, 0xF0, 0x00,
0x0C, 0x48, 0x00,
0x10, 0x84, 0x00,
0x78, 0x8A, 0x00,
0x84, 0x8A, 0x00,
0x82, 0x42, 0x00,
0x82, 0x3F, 0x00,
0x44, 0x40, 0x80,
0x38, 0xBF, 0x00,
0x20, 0x41, 0x00,
0x18, 0x3E, 0x00,
0x07, 0xC0, 0x00
};

short BIRD_WIDTH = 24;
short BIRD_HEIGHT = 12;
short BIRD_LEFT_MARGIN = 10;

static const unsigned char bitmap_pipe[] = {
0xFF, 0xFF, 0xFF, 0xE0,
0x80, 0x00, 0x00, 0x20,
0x80, 0x00, 0x00, 0x20,
0x80, 0x00, 0x00, 0x20,
0x80, 0x00, 0x00, 0x20,
0x80, 0x00, 0x00, 0x20,
0x80, 0x00, 0x00, 0x20,
0x80, 0x00, 0x00, 0x20,
0x80, 0x00, 0x00, 0x20,
0xFF, 0xFF, 0xFF, 0xE0
};

static short PIPE_WIDTH = 32;
static short PIPE_HEIGHT = 10;
static short PIPE_INTERVAL = 80;

const unsigned char bitmap_pipe_body[] = {
0x20, 0x00, 0x00, 0x80
};

#define BIRD_INIT_POSITION_Y 30
static short birdPositionY = BIRD_INIT_POSITION_Y;
//速度向上为负，向下为正
static float birdAcc = 0.4;
static short birdMaxSpeed = 5;

static float birdSpeedX = 1;
static float birdSpeedY = -1;

static int flyDistance = 0;

int isStarted = 0;

#define PIPES_COUNT 4

typedef struct pipeAttr
{
	short X;
	short Y;
	_Bool Inverse;//0开口朝上，1开口朝下
} PipeAttr;

static PipeAttr pipes[PIPES_COUNT];

void SetRandPosition(PipeAttr *pipe)
{
	if(pipe->Inverse == 0){
		pipe->Y = SSD1306_HEIGHT / 2 + rand() % (SSD1306_HEIGHT / 2);
	}else{
		pipe->Y = rand() % (SSD1306_HEIGHT / 2);
	}
}

void BirdInit(void)
{
	srand((unsigned)time(NULL));//用当前时间，设置种子
	//printf(" %d",rand()%100); //生成随机数

	//GeneratePipes
	for (short i = 0; i < PIPES_COUNT; i++)
	{
		pipes[i].X = SSD1306_WIDTH + PIPE_WIDTH + i * PIPE_INTERVAL;
		pipes[i].Inverse = i % 2;//0, 1, 0, 1, ...
		SetRandPosition(&pipes[i]);
	}
	
	birdPositionY = BIRD_INIT_POSITION_Y;
	birdSpeedY = 0;
	flyDistance = 0;
}

void GeneratePipe(PipeAttr *pipe)
{
	pipe->X = SSD1306_WIDTH + PIPE_WIDTH + PIPE_INTERVAL * PIPES_COUNT;
	SetRandPosition(pipe);
	//pipe->Y = rand() % SSD1306_HEIGHT;
}

void BirdStart(void)
{
	isStarted = 1;
}

int IsCollision(void)
{
	if(birdPositionY < 0 || birdPositionY > SSD1306_HEIGHT - BIRD_HEIGHT)
	{
		return 1;
	}

	for(int i = 0; i < PIPES_COUNT; i++) {
		if(pipes[i].X < 50) {
			if(pipes[i].X < BIRD_LEFT_MARGIN + BIRD_WIDTH
				  && pipes[i].X > BIRD_LEFT_MARGIN - PIPE_WIDTH)
			{
				if(pipes[i].Inverse == 0)
				{
					//todo:
					if(birdPositionY + BIRD_HEIGHT > pipes[i].Y)
					{
						return 1;
					}
				}
				else
				{
					if(birdPositionY < pipes[i].Y + PIPE_HEIGHT)
					{
						return 1;
					}
				}
			}
		}
	}
	return 0;
}

void GameOver(void)
{
	printf("=====Game over!!!======");
	isStarted = 0;
	ssd1306_SetCursor(10, 20);
	ssd1306_DrawString("== GAME OVER ==", Font_7x10, White);
	ssd1306_UpdateScreen();
}

int BirdLoop(void)
{
	////for test
	//birdPositionY += tmp;
	//if(birdPositionY > 60)
	//{
	//	tmp = -1;
	//}else if(birdPositionY < 0){
	//	tmp = 1;
	//}

	if(isStarted)
	{
		birdSpeedY += birdAcc;
		if(birdSpeedY < -birdMaxSpeed) birdSpeedY = -birdMaxSpeed;
		else if(birdSpeedY > birdMaxSpeed) birdSpeedY = birdMaxSpeed;
		
		birdPositionY += (short)birdSpeedY;
		flyDistance += birdSpeedX;

		//move pipes
		for (short i = 0; i < PIPES_COUNT; i++)
		{
			pipes[i].X -= birdSpeedX;
			if(pipes[i].X < -PIPE_WIDTH)
			{
				//reset pipe
				GeneratePipe(&pipes[i]);
			}
			
			//printf("%d: %d, %d\n", i, pipes[i].X, pipes[i].Y);
		}

		if(IsCollision())
		{
			printf("=====Collision!!!======");
			return 1;
		}else{
			return 0;
		}
	}
	return 0;
}

void DrawPipe(short x, short y, _Bool inverse)
{
	if (x > SSD1306_WIDTH) return;

	if(inverse == 0)
	{
		ssd1306_DrawBitmapAtPosition(bitmap_pipe, PIPE_WIDTH, PIPE_HEIGHT, x, y);
		for(short i = 0; y + PIPE_HEIGHT + i < SSD1306_HEIGHT; i++)
		{
			ssd1306_DrawBitmapAtPosition(bitmap_pipe_body, PIPE_WIDTH, 1, x, y + PIPE_HEIGHT + i);
		}
	}else{
		ssd1306_DrawBitmapAtPosition(bitmap_pipe, PIPE_WIDTH, PIPE_HEIGHT, x, y - PIPE_HEIGHT);
		for(short i = 0; y - PIPE_HEIGHT - i - 1 >= 0; i++)
		{
			ssd1306_DrawBitmapAtPosition(bitmap_pipe_body, PIPE_WIDTH, 1, x, y - PIPE_HEIGHT - i - 1);
		}
	}
}

void BirdDrawScreen(void)
{
	//1. draw bird
	ssd1306_DrawBitmapAtPosition(bitmap_bird, BIRD_WIDTH, BIRD_HEIGHT, BIRD_LEFT_MARGIN, birdPositionY);
	
	//2. draw pipes
	for (short i = 0; i < PIPES_COUNT; i++)
	{
		DrawPipe(pipes[i].X, pipes[i].Y, pipes[i].Inverse);
	}

	//3. draw score
	char buf[5];
	sprintf(buf, "%d", flyDistance / 10);
	ssd1306_SetCursor(SSD1306_WIDTH - 30, 1);
	ssd1306_DrawString(buf, Font_7x10, White);

	//DrawPipe(30, 20, 0);
	//DrawPipe(90, 40, 1);
	//ssd1306_DrawTest();

	//3. update screen
	ssd1306_UpdateScreen();
}

void BirdTest(void)
{
	ssd1306_DrawBitmapAtPosition(bitmap_bird, BIRD_WIDTH, BIRD_HEIGHT, -1, 20);
	printf("=-=-=-=\n");
	ssd1306_DrawBitmapAtPosition(bitmap_bird, BIRD_WIDTH, BIRD_HEIGHT, 60, 20);
	ssd1306_UpdateScreen();
}

void BirdFlap(void)
{
	printf("=BirdFlap=\n");
	birdSpeedY = -3.5;
}
